﻿using DAL3;
using S7.Net;
using System;
using System.Data.SqlClient;
using System.IO;
using System.IO.Ports;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace GEMINI_OP110
{
    public partial class FormMain : Form
    {
        #region 声明变量
        public string str = "未连接";
        string strs = "";
        int PLC_Count = 1;
        Socket socketSend;
        public string server = "";
        string[] typeArray = new string[150];
        string[] EMArray = new string[150];
        string[] saoma = new string[2];
        string[] leakArray = new string[3];
        string icID;
        string result;
        int num1;
        public struct proData
        {
            public static string typeName;
            public static string Ewm;
            public static string testStation;
            public static string allResult;
            public static double positivePressureValue;
            public static double negativePressureValue;
            public static string operatorter;
            public static string serialNumber;
            public static bool save;
        }
        public struct plcStructIn
        {
            public bool bool_0;
            public bool bool_1;
            public bool bool_2;
            public bool bool_3;
            public bool bool_4;
            public bool bool_5;
            public bool bool_6;
            public bool bool_7;

            public byte byte_0;
            public byte byte_1;
            public byte byte_2;//生产型号
            public byte byte_3;
            public byte byte_4;
            public byte byte_5;

            public Int16 int_0;
            public Int16 int_1;
            public Int16 int_2;
            public Int16 int_3;
            public Int16 int_4;
            public Int16 int_5;
            public Int16 int_6;
            public Int16 int_7;

        }
        //----线程循环
        bool _Continue = true;
        //----PLC监控线程数组
        Thread[] PLC_Td;
        //PLC实例数组
        public SimenesPLC[] PLC_Link;
        //PLC DB结构数组
        public plcStructIn[] Struct_Test;
        public static plcStructIn _plcStruct = new plcStructIn();
        public static FormMain FM10;
        #endregion
        public FormMain()
        {
            InitializeComponent();
            FM10 = (FormMain)this;
        }
        #region 操作窗体
        /// <summary>
        /// 打开窗体，将页面嵌入到主窗体
        /// </summary>
        /// <param name="form"></param>
        private void OpenForm(Form form)
        {
            //将当前子窗体设置成非顶级控件
            form.TopLevel = false;
            //设置窗体最大化
            form.WindowState = FormWindowState.Maximized;
            //设置窗体无边框
            form.FormBorderStyle = FormBorderStyle.None;
            //设置窗体嵌入容器
            form.Parent = this.panel1;
            form.Show();
        }
        /// <summary>
        /// 关闭窗体，将容器内窗体移除
        /// </summary>
        private void CloseForm()
        {
            //遍历这个容器里面的所有控件，找出窗体对象
            foreach (Control item in this.panel1.Controls)
            {
                if (item is Form)
                {
                    Form form = (Form)item;
                    form.Close();
                    //移除
                    this.panel1.Controls.Remove(item);
                }
            }
        }
        #endregion
        private void button4_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //嵌入窗口
            //this.CloseForm();
            FormUserLoginInterface formUserLoginInterface = new FormUserLoginInterface();
            //this.OpenForm(formUserLoginInterface);
            formUserLoginInterface.Show();
        }

        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            PLC_Link[0].plc.WriteBit(DataType.DataBlock, 99, 230, 4, 0);
            //关闭主窗体时释放后台线程的资源
            for (int I = 0; I < PLC_Count; I++)
            {
                if (PLC_Td[I] != null)
                {
                    PLC_Td[I].Abort();
                }
            }
        }

        private void FormMain_Load(object sender, EventArgs e)
        {
            //取消跨线程的访问
            Control.CheckForIllegalCrossThreadCalls = false;
            #region 连接PLC
            PLC_Td = new Thread[PLC_Count];
            PLC_Link = new SimenesPLC[PLC_Count];
            Struct_Test = new plcStructIn[PLC_Count];
            for (int I = 0; I < PLC_Count; I++)
            {
                PLC_Td[I] = new Thread(PLC_Td_Func);
                PLC_Td[I].IsBackground = true;
                PLC_Td[I].Start(I);
            }
            #endregion
            timer.Enabled = true;
            timer.AutoReset = true;
            timer.Interval = 1000;
            timer.AutoReset = false;
            timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
            timercall.Enabled = true;
            timercall.AutoReset = true;
            timercall.Interval = 1000;
            timercall.AutoReset = false;
            timercall.Elapsed += new System.Timers.ElapsedEventHandler(timercall_Elapsed);
            #region 与服务器tcp/ip通讯建立连接
            try
            {
                //创建负责通信的Socket
                socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPAddress ip = IPAddress.Parse("172.16.150.1");
                IPEndPoint point = new IPEndPoint(ip, 50001);
                //获得要连接的远程服务器应用程序的IP地址和端口号
                socketSend.Connect(point);
                server = "成功";

                //开启一个新的线程不停的接收服务端发来的消息
                Thread th = new Thread(Recive);
                th.IsBackground = true;
                th.Start();
            }
            catch
            {
                server = "失败";
            }
            #endregion

            #region 向服务器获取所有产品型号和扫码设置
            string sql = "select [typeName] from parameterSetting";
            SqlDataReader objReader = SQLHelp.GetReader(sql);
            int temp2 = 0;
            while (objReader.Read())
            {
                //EMArray[temp2] = objReader["OP70扫码"].ToString();
                typeArray[temp2] = objReader["typeName"].ToString();
                comboBox1.Items.Add(typeArray[temp2]);
                //comboBox2.Items.Add(EMArray[temp2]);
                temp2 += 1;
            }
            objReader.Close();
            #endregion

            //#region 设置串口参数并打开串口接收
            ////波特率

            ////IC卡
            ////serialPort1.BaudRate = 9600;
            ////扫码
            //serialPort2.BaudRate = 57600;

            ////数据位

            ////IC卡
            ////serialPort1.DataBits = 8;
            ////扫码
            //serialPort2.DataBits = 8;

            ////奇偶校验位
            ////serialPort1.Parity = System.IO.Ports.Parity.None;
            //serialPort2.Parity = System.IO.Ports.Parity.None;

            ////停止位
            ////serialPort1.StopBits = System.IO.Ports.StopBits.One;
            //serialPort2.StopBits = System.IO.Ports.StopBits.One;

            //string[] contents = new string[5];
            //try
            //{
            //    contents = File.ReadAllLines(Application.StartupPath + "\\COM口配置.txt", Encoding.UTF8);
            //}
            //catch
            //{
            //    label28.Text += "请检查COM口配置文件！";
            //}
            ////端口
            ////try
            ////{
            ////    serialPort1.PortName = contents[0];
            ////    serialPort1.DataReceived += new SerialDataReceivedEventHandler(SerialPort1_DataReceived);
            ////    serialPort1.Open();

            ////}
            ////catch
            ////{
            ////    MessageBox.Show("IC卡端口打开失败，请检查串口连接是否正确！", "错误提示");
            ////}

            //try
            //{
            //    serialPort2.PortName = contents[1];
            //    serialPort2.DataReceived += new SerialDataReceivedEventHandler(SerialPort2_DataReceived);
            //    serialPort2.Open();
            //}
            //catch
            //{
            //    MessageBox.Show("扫码端口打开失败，请检查串口连接是否正确！", "错误提示");
            //}
            //#endregion
            AppearanceDetectionStation.Form12 formMain = GenericSingleton<AppearanceDetectionStation.Form12>.CreateInstrance();
            formMain.Show();
        }
        //PLC线程
        public static string ID;
        private void PLC_Td_Func(object ob)
        {
            Ping p = new Ping();
            int num = (int)ob;

            string[] PLC_IP = new string[PLC_Count];
            PLC_IP[0] = "172.16.1.2";
            PLC_Link[num] = new SimenesPLC(CpuType.S71500, PLC_IP[num].ToString(), 0, 1);
            while (_Continue)
            {
                try
                {
                    //处理相应的PLC对象的数据处理
                    if (p.Send(PLC_IP[num], 200).Status == IPStatus.Success)//如果200ms时间间隔ping通了
                    {
                        if (PLC_Link[num].plc.IsConnected == false)//plc没有连接上
                        {
                            int s = (int)PLC_Link[num].plc.Open();
                            strs = Convert.ToString(s);
                            if (s == 0)
                            {
                                str = "成功";
                            }
                            else
                            {
                                str = "失败";
                            }
                        }
                        else
                        {
                            //读取DB
                            Struct_Test[num] = (plcStructIn)PLC_Link[num].plc.ReadStruct(typeof(plcStructIn), 99, 504);
                            _plcStruct = Struct_Test[num];
                            ID = PLC_Link[num].plc.Read(DataType.DataBlock, 99, 528, VarType.DInt, 1).ToString();   //99.528才是OP90的ID.
                            if (AppearanceDetectionStation.FormMain.goSelect /*&& !proData.save*/)   //proData.save为TRUE时数据记录完成，并且托盘开始流走
                            {
                                #region 向服务器获取内部码
                                //string sql = "select [ID] from productData where [内部码] = '" + label37.Text + "'";
                                string sql = "select [内部码] from productData where [ID]= '" + ID + "'";
                                SqlDataReader objReader = SQLHelp.GetReader(sql);
                                while (objReader.Read())
                                {
                                    AppearanceDetectionStation.FormMain.neibuma = objReader["内部码"].ToString();
                                }
                                objReader.Close();
                                #endregion
                                label20.Text = AppearanceDetectionStation.FormMain.neibuma;
                            }
                            //拍照完成
                            AppearanceDetectionStation.FormMain.photoDone = (bool)PLC_Link[num].plc.Read(DataType.DataBlock, 99, 504, VarType.Bit, 1,4);  //DB99.504.4是过程完成信号
                            if ((Byte)PLC_Link[num].plc.Read(DataType.DataBlock, 99, 2, VarType.Byte, 1) > 0)
                            {
                                #region 向服务器获取所有产品型号和扫码设置
                                string sql = "select [typeName] from parameterSetting";
                                SqlDataReader objReader = SQLHelp.GetReader(sql);
                                int temp2 = 0;
                                while (objReader.Read())
                                {
                                    if (temp2 == 0)
                                    {
                                        comboBox1.Items.Clear();
                                        //comboBox2.Items.Clear();
                                    }
                                    //EMArray[temp2] = objReader["OP70扫码"].ToString();
                                    typeArray[temp2] = objReader["typeName"].ToString();
                                    comboBox1.Items.Add(typeArray[temp2]);
                                    //comboBox2.Items.Add(EMArray[temp2]);
                                    temp2 += 1;
                                }
                                objReader.Close();
                                #endregion
                            }
                            //retry
                            AppearanceDetectionStation.FormMain.retry = (bool)PLC_Link[num].plc.Read(DataType.DataBlock, 99, 504, VarType.Bit, 1, 0)/*PLC_Link[num].readBoolen("DB99.DBX532.0")*/;
                            if (AppearanceDetectionStation.FormMain.delete)
                            {
                                //PLC_Link[num].WriteBoolen("DB99.DBX532.0", false);
                                PLC_Link[num].plc.WriteBit(DataType.DataBlock, 99, 504, 0, 0);
                                AppearanceDetectionStation.FormMain.delete = false;
                            }
                            #region  报警记录
                            //报警记录
                            if (_plcStruct.bool_5)
                            {
                                //inAlarm("OA报警[1]夹紧气缸前进超时A");            

                            }
                            else if (_plcStruct.bool_5)
                            {
                                //inAlarm("OA报警[2]夹紧气缸返回超时A");
                            }

                            #endregion

                            //型号
                            if (_plcStruct.byte_2 > 0)
                            {
                                label2.Text = typeArray[_plcStruct.byte_2 - 1];
                            }

                            //托盘号
                            label5.Text = _plcStruct.byte_3.ToString();
                            //测试时间
                            label7.Text = _plcStruct.int_5 / 60 + "分" + _plcStruct.int_5 % 60 + "秒";
                            //计划生产数
                            label9.Text = _plcStruct.int_0.ToString();
                            //当前生产数
                            label11.Text = _plcStruct.int_1.ToString();
                            //合格数
                            label13.Text = _plcStruct.int_2.ToString();
                            //不合格数
                            label15.Text = _plcStruct.int_3.ToString();
                            //复测数
                            label34.Text = _plcStruct.int_4.ToString();

                            if (_plcStruct.bool_5)
                            {
                                result = "合格";
                                label26.Text = "合格";
                                label26.BackColor = System.Drawing.Color.Green;
                            }
                            else if (_plcStruct.bool_6)
                            {
                                result = "不合格";
                                label26.Text = "不合格";
                                label26.BackColor = System.Drawing.Color.Red;
                            }
                            else
                            {
                                result = "未测试";
                                label26.Text = "未测试";
                                label26.BackColor = System.Drawing.Color.Silver;
                                if (proData.save)
                                {
                                    //PLC_Link[0].plc.WriteBit(DataType.DataBlock, 99, 240, 0, 0);
                                    //PLC_Link[0].plc.WriteBit(DataType.DataBlock, 99, 240, 1, 0);
                                }
                                proData.save = false;
                            }

                            //数据记录
                            proData.operatorter = Program.userlogin.Admin;//操作员
                            label39.Text = Program.userlogin.Admin;
                            label40.Text = Program.userlogin.serialNumber.ToString();
                            if (Program.userlogin.Admin != "")
                            {
                                PLC_Link[0].plc.WriteBit(DataType.DataBlock, 99, 240, 4, 1);
                            }
                            else
                            {
                                PLC_Link[0].plc.WriteBit(DataType.DataBlock, 99, 240, 4, 0);
                            }
                            if (_plcStruct.bool_4 && proData.save == false)
                            {
                                ////过程完成后开始进行照片存储
                                //AppearanceDetectionStation.FormMain.photoDone = true;
                                //历史记录
                                string sql = "update productData set [OP90结果]='{0}',[OP90操作时间]='{1}' where [ID] = '{2}'";
                                sql = string.Format(sql, result, label7.Text, ID);
                                num1 = SQLHelp.AddData(sql);
                                if (num1 > 0)
                                {
                                    PLC_Link[0].plc.WriteBit(DataType.DataBlock, 99, 230, 2, 1);
                                }
                                

                                proData.save = true;
                            }
                        }
                    }
                    else
                    {
                        PLC_Link[num].plc.Close();
                        str = "ping失败";
                    }
                    if (p.Send("172.16.1.7", 200).Status == IPStatus.Success)
                    {
                        server = "成功";
                    }
                    else
                    {
                        server = "ping失败";
                    }
                }
                catch (Exception ex1)
                {
                    str = "出现异常";
                    MessageBox.Show(Convert.ToString(ex1), "错误提示!");
                }

                if (str.Equals("成功"))
                {
                    label23.BackColor = System.Drawing.Color.Green;
                }
                else
                {
                    label23.BackColor = System.Drawing.Color.Red;
                }
                if (server.Equals("成功"))
                {
                    label22.BackColor = System.Drawing.Color.Green;
                }
                else
                {
                    label22.BackColor = System.Drawing.Color.Green;
                }
                Thread.Sleep(100);

                label242.Text = "使用公司：空调国际(上海)有限公司   \t 设备公司：重庆英之拓智能设备有限公司  \t  软件版本号：V1.0";
                label242.Text = string.Format(label242.Text, Program.userlogin.name);
            }

        }

        /// <summary>
        /// 不停的接受服务器发来的消息
        /// </summary>
        void Recive()
        {
            while (true)
            {
                try
                {
                    byte[] buffer = new byte[1024];
                    int r = socketSend.Receive(buffer);
                    //实际接收到的有效字节数
                    if (r == 0)
                    {
                        break;
                    }
                    //表示发送的字符消息,并且是所有产品型号
                    if (buffer[0] == 0)
                    {
                        string s = Encoding.UTF8.GetString(buffer, 1, r - 1);

                        //0 5 ,aaa,asas,dsds,gfhh,hhggh,
                        //截取所有型号
                        typeArray = s.Split(new Char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                    }
                    //表示发送的字符消息,并且是扫码参数
                    if (buffer[0] == 1)
                    {
                        string s = Encoding.UTF8.GetString(buffer, 1, r - 1);
                        //1,hhggh
                        //截取扫码参数设置
                        saoma = s.Split(new Char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                    }
                    //else if (buffer[0] == 1)
                    //{
                    //    SaveFileDialog sfd = new SaveFileDialog();
                    //    sfd.InitialDirectory = @"C:\Users\SpringRain\Desktop";
                    //    sfd.Title = "请选择要保存的文件";
                    //    sfd.Filter = "所有文件|*.*";
                    //    sfd.ShowDialog(this);
                    //    string path = sfd.FileName;
                    //    using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
                    //    {
                    //        fsWrite.Write(buffer, 1, r - 1);
                    //    }
                    //    MessageBox.Show("保存成功");
                    //}
                    //else if (buffer[0] == 2)
                    //{
                    //    ZD();
                    //}

                }
                catch { }

            }
        }
        #region rs232通讯
        //IC卡
        private void SerialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            try
            {

                Thread.Sleep(50);
                byte[] byteRead1 = new byte[serialPort1.BytesToRead];
                serialPort1.Read(byteRead1, 0, byteRead1.Length);
                byte[] temp6 = new byte[1];
                temp6[0] = byteRead1[20];
                icID = byteToHexStr(temp6, 1);
                Program.userlogin = UserManagement.GetUser(Convert.ToInt32(icID));
                label242.Text = "当前登录用户：{0} \t\t  使用公司：空调国际(上海)有限公司   \t 设备公司：重庆英之拓智能设备有限公司  \t  软件版本号：V1.0";
                label242.Text = string.Format(label242.Text, Program.userlogin.name);
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc + "接收失败");
            }

        }
        //
        private void SerialPort2_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            try
            {
                Thread.Sleep(100);
                byte[] byteRead = new byte[serialPort2.BytesToRead];
                serialPort2.Read(byteRead, 0, byteRead.Length);
                string indata = Encoding.ASCII.GetString(byteRead);
                
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc + "接收失败");
            }

        }
        #endregion
        public string byteToHexStr(byte[] bytes, int len)  //数组转十六进制字符
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < len; i++)
                {
                    returnStr += bytes[i].ToString("X2");
                }
            }
            return returnStr;
        }
        private static byte[] strToToHexByte(string hexString) //字符串转16进制
        {
            //hexString = hexString.Replace(" ", " "); 
            if ((hexString.Length % 2) != 0)
                hexString = "0" + hexString;
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }
        //计数清零
        private void button2_MouseDown(object sender, MouseEventArgs e)
        {
            PLC_Link[0].plc.WriteBit(DataType.DataBlock, 99, 240, 3, 1);
        }

        private void button2_MouseUp(object sender, MouseEventArgs e)
        {
            PLC_Link[0].plc.WriteBit(DataType.DataBlock, 99, 240, 3, 0);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            label18.Text = DateTime.Now.ToString("yyyy/MM/dd");
            label19.Text = DateTime.Now.ToLongTimeString();
            
        }
        //防止重复打开窗体
        public class GenericSingleton<T> where T : Form, new()
        {
            private static T t = null;
            public static T CreateInstrance()
            {
                if (t == null || t.IsDisposed)
                {
                    t = new T();
                }
                else
                {
                    t.Activate(); //如果已经打开过就让其获得焦点  
                    t.WindowState = FormWindowState.Normal;//使Form恢复正常窗体大小
                }
                return t;
            }
        }
        static string GetLatestFileNameInfo(string dir, string ext)
        {
            DirectoryInfo d = new DirectoryInfo(dir);
            DateTime temp = new DateTime();
            string FileName = "0";
            foreach (FileInfo file in d.GetFiles())
            {
                if (file.Extension.ToUpper() == ext.ToUpper())
                {
                    if (file.CreationTime > temp)
                    {
                        temp = file.CreationTime;
                        FileName = file.FullName;
                    }
                }
            }

            return FileName;
        }
        private bool IsNumeric(string str)
        {

            foreach (char c in str)
            {
                if (!Char.IsNumber(c))
                {
                    return false;
                }
            }
            return true;
        }
        //call the monitor
        int secondCount;
        int secondCount1;
        System.Timers.Timer timer = new System.Timers.Timer();
        System.Timers.Timer timercall = new System.Timers.Timer();
        private void button7_Click(object sender, EventArgs e)
        {
            PLC_Link[0].plc.WriteBit(DataType.DataBlock, 99, 618, 4, !Convert.ToBoolean(PLC_Link[0].plc.Read(DataType.DataBlock, 99, 618, VarType.Bit, 1, 4)));
            if (Convert.ToBoolean(PLC_Link[0].plc.Read(DataType.DataBlock, 99, 618, VarType.Bit, 1, 4)))
            {
                timer.Start();
                secondCount = 0;
            }
            if (Convert.ToBoolean(PLC_Link[0].plc.Read(DataType.DataBlock, 99, 618, VarType.Bit, 1, 4)) == false)
            {
                timer.Stop();
                string sql = "insert into calRecord([callStation],[callOP],[callOptions],[callTimers]) values('{0}','{1}','{2}','{3}')";
                sql = string.Format(sql, "OP110", proData.operatorter, "呼叫班长", secondCount);
                num1 = SQLHelp.AddData(sql);
            }
        }

        private void button8_Click(object sender, EventArgs e)
        {
            PLC_Link[0].plc.WriteBit(DataType.DataBlock, 99, 618, 5, !Convert.ToBoolean(PLC_Link[0].plc.Read(DataType.DataBlock, 99, 618, VarType.Bit, 1, 5)));
            if (Convert.ToBoolean(PLC_Link[0].plc.Read(DataType.DataBlock, 99, 618, VarType.Bit, 1, 5)))
            {
                timercall.Start();
                secondCount1 = 0;
            }
            if (Convert.ToBoolean(PLC_Link[0].plc.Read(DataType.DataBlock, 99, 618, VarType.Bit, 1, 5)) == false)
            {
                timercall.Stop();

                string sql = "insert into calRecord([callStation],[callOP],[callOptions],[callTimers]) values('{0}','{1}','{2}','{3}')";
                sql = string.Format(sql, "OP110", proData.operatorter, "呼叫物料", secondCount1);
                num1 = SQLHelp.AddData(sql);
            }
        }
        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            secondCount++;
            timer.Start();
        }
        void timercall_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            secondCount1++;
            timercall.Start();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            //AppearanceDetectionStation.FormMain formMain = new AppearanceDetectionStation.FormMain();
            //formMain.Show();
            AppearanceDetectionStation.Form12 formMain = GenericSingleton<AppearanceDetectionStation.Form12>.CreateInstrance();
            formMain.Show();
        }
    }
}
